package robots.domain;

import java.io.Serializable;
import java.util.Random;

import robots.excepcions.DineroInsuficienteException;
import robots.excepcions.RobotEnNullException;

public class CompraVentaDeRobots implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -5546509936327978537L;

	/**
	 * Cuando se rechaza la oferta del sistema, en el proceso de venta de un
	 * robot por parte del jugador, aumenta el daño del mismo en 1%
	 * 
	 * @param robotAVender
	 */
	public void rechazarOferta(Robot robotAVender) {
		robotAVender.aumnetarDanioEn(1);
	}

	/**
	 * Utilizado por el sistema cuando el jugador inicia el proceso de venta de
	 * un robot.
	 * 
	 * @param precioRobot
	 * @return oferta del sistema
	 */
	public int ofertarPorUnRobot(Integer precioRobot) {
		double indice = (1 - ((double) (new Random().nextInt(9)) + 2) / 100);
		return (int) (precioRobot * indice);
	}

	/**
	 * Inicia el proceso de oferta para comprar un robot. Se conoce al robot
	 * seleccionado, el jugador y el dinero que oferta. En caso que el sistema
	 * acepte la oferta, se concreta la compra; caso contrario se descuenta un
	 * porcentaje de la oferta al dinero del jugador.
	 * 
	 * @param robotSeleccionado
	 * @param oferta
	 * @param comprador
	 * @param sistema
	 * @return si la oferta fue aceptada o no.
	 * @throws RobotEnNullException 
	 * @throws Exception
	 */
	public boolean offer(Robot robotSeleccionado, int oferta,
			Jugador comprador, Jugador sistema) throws DineroInsuficienteException, RobotEnNullException {
		boolean aceptaOferta= false;
		if (robotSeleccionado == null)
			throw new RobotEnNullException();
		else {
			aceptaOferta = (Math.random()) <= (Math.pow(
					(0.9 * ((double) oferta / robotSeleccionado.getPrecio())), 2));
			if (aceptaOferta) {
				this.purchase(robotSeleccionado, oferta, comprador, sistema);
			} else {
				comprador.cobrar((int) (oferta * 0.02));
			}
		}	
		return aceptaOferta;
	}

	/**
	 * Compra concreta. Es llamado unicamente de offer. Le cobra al jugador el
	 * dinero ofertado, le agrega el robot a su coleccion. Por ultimo, se quita
	 * el robot del sistema, ya que cuenta con nuevo duenio (se setea al jugador
	 * como su nuevo duenio).
	 * 
	 * @param robotAComprar
	 * @param oferta
	 * @param comprador
	 * @param sistema
	 * @throws Exception
	 */
	public void purchase(Robot robotAComprar, int oferta, Jugador comprador,
			Jugador sistema) throws DineroInsuficienteException {
		comprador.cobrar(oferta);
		comprador.agregarRobot(robotAComprar);
		robotAComprar.nuevoDuenio(comprador);
		sistema.quitarRobot(robotAComprar);
	}

	/**
	 * Venta de robot concreta. Una vez que el jugador acepta la oferta del
	 * sistema, este paga el dinero correspondiente, se le quita el robot, se
	 * setea el duenio en null y se agrega al sistema.
	 * 
	 * @param oferta
	 * @param robotAVender
	 * @param jugador
	 * @param sistema
	 */
	public void sell(int oferta, Robot robotAVender, Jugador vendedor,
			Jugador sistema) {
		vendedor.pagar(oferta);
		vendedor.quitarRobot(robotAVender);
		robotAVender.nuevoDuenio(null);
		sistema.agregarRobot(robotAVender);
	}
}
